#include "circular_buffer.h"
#include <stdlib.h>
#include <string.h>

// 初始化缓冲区
bool circular_buffer_init(CircularBuffer *buf, size_t capacity) {
    buf->data = (uint8_t *)malloc(capacity);
    if (!buf->data) return false;
    
    buf->capacity = capacity;
    buf->head = buf->tail = 0;
    pthread_mutex_init(&buf->mutex, NULL);
    pthread_cond_init(&buf->cond, NULL);
    return true;
}

// 销毁缓冲区
void circular_buffer_free(CircularBuffer *buf) {
    if (buf->data) free(buf->data);
    pthread_mutex_destroy(&buf->mutex);
    pthread_cond_destroy(&buf->cond);
}

// 写入数据（非阻塞）
bool circular_buffer_write(CircularBuffer *buf, const uint8_t *data, size_t len) {
    pthread_mutex_lock(&buf->mutex);
    
    // 计算剩余空间
    size_t avail = (buf->tail > buf->head) ? 
                   (buf->tail - buf->head - 1) : 
                   (buf->capacity - buf->head + buf->tail - 1);
    if (len > avail) {
        pthread_mutex_unlock(&buf->mutex);
        return false;  // 空间不足
    }

    // 写入数据（处理环形回绕）
    for (size_t i = 0; i < len; i++) {
        buf->data[buf->head] = data[i];
        buf->head = (buf->head + 1) % buf->capacity;
    }

    pthread_cond_signal(&buf->cond);  // 通知消费者
    pthread_mutex_unlock(&buf->mutex);
    return true;
}

// 读取数据（阻塞直到有数据）
size_t circular_buffer_read(CircularBuffer *buf, uint8_t *out, size_t max_len) {
    pthread_mutex_lock(&buf->mutex);
    
    // 等待数据到达
    while (buf->head == buf->tail) {
        pthread_cond_wait(&buf->cond, &buf->mutex);
    }

    // 计算可读数据量
    size_t avail = (buf->head > buf->tail) ? 
                   (buf->head - buf->tail) : 
                   (buf->capacity - buf->tail);
    size_t to_read = (avail < max_len) ? avail : max_len;

    // 读取数据（处理环形回绕）
    for (size_t i = 0; i < to_read; i++) {
        out[i] = buf->data[buf->tail];
        buf->tail = (buf->tail + 1) % buf->capacity;
    }

    pthread_mutex_unlock(&buf->mutex);
    return to_read;
}

// 获取可读数据量
size_t circular_buffer_available(CircularBuffer *buf) {
    pthread_mutex_lock(&buf->mutex);
    size_t avail = (buf->head >= buf->tail) ? 
                   (buf->head - buf->tail) : 
                   (buf->capacity - buf->tail + buf->head);
    pthread_mutex_unlock(&buf->mutex);
    return avail;
}

// 清空缓冲区
void circular_buffer_clear(CircularBuffer *buf) {
    pthread_mutex_lock(&buf->mutex);
    buf->head = buf->tail = 0;
    pthread_mutex_unlock(&buf->mutex);
}